package com.five.second_shop.controller.User;

import com.alibaba.fastjson.JSON;
import com.five.second_shop.entity.Login;
import com.five.second_shop.entity.UserInfo;
import com.five.second_shop.entity.UserRole;
import com.five.second_shop.service.LoginService;
import com.five.second_shop.service.MailService;
import com.five.second_shop.service.UserInfoService;
import com.five.second_shop.service.UserRoleService;
import com.five.second_shop.util.*;
import com.five.second_shop.vo.ResultVo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Controller
public class LoginController {
    @Autowired
    private LoginService loginService;
    @Autowired
    private MailService mailService;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private UserRoleService userRoleService;

    //导入模板引擎
    @Autowired
    private TemplateEngine templateEngine;
    /**邮箱号和注册验证码map集合*/
    private static Map<String, String> mailcodemap1 = new HashMap<>();



    /**登录
     * 1.判断输入账号的类型
     * 2.登录
     * */
    @ResponseBody
    @PostMapping("/user/login")
    public ResultVo userLogin(@RequestBody Login login, HttpSession session){
        String account=login.getUsername();
        String password=login.getPassword();
        String vercode=login.getVercode();
        UsernamePasswordToken token;
        if(!ValidateCode.code.equalsIgnoreCase(vercode)){
            return new ResultVo(false, StatusCode.ERROR,"请输入正确的验证码");
        }
        //判断输入的账号是邮箱
        if (!JustMail.justMail(account)) {
            //输入的是用户名
            String username = account;
            //盐加密
            token=new UsernamePasswordToken(username, new Md5Hash(password,"Campus-shops").toString());
        }else {
            //输入的是手机号
            String email = account;
            login.setEmail(email);
            //将封装的login中username变为null
            login.setUsername(null);
            //盐加密
            token=new UsernamePasswordToken(email, new Md5Hash(password,"Campus-shops").toString());
        }
        Subject subject= SecurityUtils.getSubject();
        try {
            subject.login(token);
            //盐加密
            String passwords = new Md5Hash(password, "Campus-shops").toString();
            login.setPassword(passwords);
            Login login1 = loginService.userLogin(login);
            session.setAttribute("userid",login1.getUserid());
            session.setAttribute("username",login1.getUsername());
            return new ResultVo(true,StatusCode.OK,"登录成功");
        }catch (UnknownAccountException e){
            return new ResultVo(true,StatusCode.LOGINERROR,"用户名不存在");
        }catch (IncorrectCredentialsException e){
            return new ResultVo(true,StatusCode.LOGINERROR,"密码错误");
        }
    }


    /**
     *图片验证码
     * */
    @RequestMapping(value = "/images", method = {RequestMethod.GET, RequestMethod.POST})
    public void images(HttpServletResponse response) throws IOException {
        response.setContentType("image/jpeg");
        //禁止图像缓存。
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        ValidateCode vCode = new ValidateCode(820, 200, 5, 80);
        vCode.write(response.getOutputStream());
    }

    /**
     * 发送电子邮件 根据不同type 设置不同内容
     * @param User
     * @return
     */
    @RequestMapping("/sendEmail")
    @ResponseBody
    public ResultVo sendEmail(@RequestBody String User){
        HashMap map = JSON.parseObject(User, HashMap.class);
        String email = map.get("email").toString();
        String type = map.get("type").toString();
        Login login = new Login();
        login.setEmail(email);

        if(!type.equals("0")){
            return new ResultVo(false, StatusCode.ACCESSERROR,"违规操作");
        }

        if(!JustMail.justMail(email)){
            return new ResultVo(false,StatusCode.ERROR,"请输入正确格式的邮箱");
        }

        Login isExist = loginService.userLogin(login);
        if (isExist!=null){
            return new ResultVo(false, StatusCode.ERROR,"该邮箱已经注册过了");
        }

        Context context = new Context();
        String subject = "二手网站验证码";
        String code = GetCode.phonecode();
        context.setVariable("id",code);
        context.setVariable("title","用户注册");
        String emailContent = templateEngine.process("common/emailTemplate",context);
        try {
            mailService.sendHtmlMail(email,subject,emailContent);
        } catch (Exception e) {
            return new ResultVo(false,StatusCode.ERROR,"验证码发送失败");
        }
        /*放入mailCodeMap中以备验证*/
        mailcodemap1.put(email,code);
        return new ResultVo(true,StatusCode.OK,"验证码发送成功！注意查收");
    }

    /**
     * 用户注册
     * @param userInfo 传入的学生用户信息
     * @param session
     * @return
     */
    @ResponseBody
    @PostMapping("/user/register")
    public  ResultVo userReg(@RequestBody UserInfo userInfo, HttpSession session) {
        String username = userInfo.getUsername();
        String password = userInfo.getPassword();
        String email = userInfo.getEmail();
        String vercode = userInfo.getVercode();
        Login login = new Login().setEmail(email);
        //查询账号是否已经注册
        Login userIsExist = loginService.userLogin(login);
        if (!StringUtils.isEmpty(userIsExist)){//用户账号已经存在
            return new ResultVo(false, StatusCode.ERROR,"该邮箱已经注册过了");
        }
        login.setUsername(username).setEmail(null);
        Login userNameIsExist = loginService.userLogin(login);
        if (!StringUtils.isEmpty(userNameIsExist)){//用户名已经存在
            return new ResultVo(false, StatusCode.ERROR,"用户名已存在，请换一个吧");
        }
        String rel = mailcodemap1.get(email);
        if (StringUtils.isEmpty(rel)) {//验证码到期 或者 没发送短信验证码
            return new ResultVo(false,StatusCode.ERROR,"请重新获取验证码");
        }
        if (rel.equalsIgnoreCase(vercode)) {//验证码正确
            //盐加密
            String passwords = new Md5Hash(password, "Campus-shops").toString();
            /*由工具类得到uid*/
            String userid = KeyUtil.genUniqueKey();
            login.setId(KeyUtil.genUniqueKey()).setUserid(userid).setEmail(email).setPassword(passwords);
            Integer integer = loginService.loginAdd(login);
            //新注册用户存入默认头像、存入默认签名
            userInfo.setUserid(userid).setPassword(passwords).setUimage("/pic/d1d66c3ea71044a9b938b00859ca94df.jpg").
                    setSign("我寄清风与明月，随风直到夜郎西").setStatus("offline");
            Integer integer1 = userInfoService.userReg(userInfo);
            if (integer==1 && integer1==1){
                /**注册成功后存入session*/
                session.setAttribute("userid",userid);
                session.setAttribute("username",username);
                /**存入用户角色信息*/
                userRoleService.InsertUserRole(new UserRole().setUserid(userid).setRoleid(1).setIdentity("网站用户"));
                UsernamePasswordToken token=new UsernamePasswordToken(email, new Md5Hash(password,"Campus-shops").toString());
                Subject subject= SecurityUtils.getSubject();
                subject.login(token);
                return new ResultVo(true,StatusCode.OK,"注册成功");
            }
            return new ResultVo(false,StatusCode.ERROR,"注册失败");
        }
        return new ResultVo(false,StatusCode.ERROR,"验证码错误");
    }

    /**
     * 发送电子邮件 根据不同type 设置不同内容
     * @param request 前端发送的邮件名称 操作类型
     * @return
     */
    @RequestMapping("/user/sendresetpwd")
    @ResponseBody
    public ResultVo sendresetpwd(@RequestBody String request){
        HashMap map = JSON.parseObject(request, HashMap.class);
        String email = map.get("email").toString();
        String type = map.get("type").toString();
        Login login = new Login();
        login.setEmail(email);

        if(!type.equals("1")){
            return new ResultVo(false, StatusCode.ACCESSERROR,"违规操作");
        }

        if(!JustMail.justMail(email)){
            return new ResultVo(false,StatusCode.ERROR,"请输入正确格式的邮箱");
        }

        Login isExist = loginService.userLogin(login);
        if (isExist == null){
            return new ResultVo(false, StatusCode.ERROR,"用户不存在，请先注册");
        }

        Context context = new Context();
        String subject = "二手网站验证码";
        String code = GetCode.phonecode();
        context.setVariable("id",code);
        context.setVariable("title","忘记密码");
        String emailContent = templateEngine.process("common/emailTemplate",context);
        try {
            mailService.sendHtmlMail(email,subject,emailContent);
        } catch (Exception e) {
            return new ResultVo(false,StatusCode.ERROR,"验证码发送失败");
        }
        /*放入mailCodeMap中以备验证*/
        mailcodemap1.put(email,code);
        return new ResultVo(true,StatusCode.OK,"验证码发送成功！注意查收");
    }


    /**重置密码
     * 1.判断手机号格式是否正确
     * 2.查询手机号是否存在
     * 3.判断验证码是否有效或正确
     * 4.重置密码
     * */
    @ResponseBody
    @PostMapping("/user/resetpwd")
    public  ResultVo resetpwd(@RequestBody Login login) {
        String email=login.getEmail();
        String password=login.getPassword();
        String vercode=login.getVercode();
        Login login1 = new Login();
        UserInfo userInfo = new UserInfo();
        if (!JustMail.justMail(email)) {//判断输入的手机号格式是否正确
            return new ResultVo(false,StatusCode.ERROR,"请输入正确格式的邮箱");
        }
        //查询手机号是否存在
        login1.setEmail(email);
        Login userIsExist = loginService.userLogin(login1);
        if (StringUtils.isEmpty(userIsExist)){//用户账号不存在
            return new ResultVo(false, StatusCode.LOGINERROR,"该账号不存在");
        }
        String rel = mailcodemap1.get(email);
        if (StringUtils.isEmpty(rel)) {//验证码到期 或者 没发送短信验证码
            return new ResultVo(false,StatusCode.ERROR,"请重新获取验证码");
        }
        if (rel.equalsIgnoreCase(vercode)) {//验证码正确
            //盐加密
            String passwords = new Md5Hash(password, "Campus-shops").toString();
            login1.setPassword(passwords).setId(userIsExist.getId()).setMobilephone(null);
            userInfo.setEmail(email).setPassword(passwords).setUserid(userIsExist.getUserid());
            Integer integer = loginService.updateLogin(login1);
            Integer integer1 = userInfoService.UpdateUserInfo(userInfo);
            if (integer==1 && integer1==1){
                return new ResultVo(true,StatusCode.OK,"重置密码成功");
            }
            return new ResultVo(false,StatusCode.ERROR,"重置密码失败");
        }
        return new ResultVo(false,StatusCode.ERROR,"验证码错误");
    }
}
